﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using XBS.Model;

using System.Xml.Linq;
using System.IO.IsolatedStorage;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Media;
using System.Reflection;

namespace XBS.ViewModel
{
    public class VM : INotifyPropertyChanged
    {
        private static List<Color> PresetColors = new List<Color>() { Colors.White, Colors.Red, Colors.Black, Colors.Brown, Colors.Gray, Colors.Green };

        public static string KEY_RECENT_STORIES_INDEX = "recentStoriesIndex";
        public static string KEY_BOOKMARKED_PARAGRAPH = "bookmarkParagraph";
        public static string KEY_FONT_SIZE = "userFontSize";
        public static string KEY_TEXT_COLOR = "userTextColor";
        public static string KEY_BACKGROUND_COLOR = "userBackgroundColor";

        public static int MAX_RECENT_STORIES = 9;
        public static double DEFAULT_FONT_SIZE = 24;
        public static Color DEFAULT_TEXT_COLOR = Colors.White;
        public static Color DEFAULT_BACKGROUND_COLOR = Colors.Brown;

        public VM()
        {
            listStoryItems = new ObservableCollection<Story>();
            listStoriesIndex = new List<string>();
            listRecentStories = new ObservableCollection<Story>();
            listBookmarks = new ObservableCollection<Bookmark>();
            listBackgroundColor = new ObservableCollection<CustomColor>();
            listTextColor = new ObservableCollection<CustomColor>();
        }

        private ObservableCollection<Story> listStoryItems;
        public ObservableCollection<Story> ListStoryItems
        {
            get
            {
                return listStoryItems;
            }
            set
            {
                listStoryItems = value;
                RaisePropertyChanged("ListStoryItems");
            }
        }

        private List<string> listStoriesIndex;

        private ObservableCollection<Story> listRecentStories;
        public ObservableCollection<Story> ListRecentStories
        {
            get
            {
                return listRecentStories;
            }
            set
            {
                listRecentStories = value;
                RaisePropertyChanged("ListRecentStories");
            }
        }

        private ObservableCollection<Bookmark> listBookmarks;
        public ObservableCollection<Bookmark> ListBookmarks
        {
            get
            {
                return listBookmarks;
            }
            set
            {
                listBookmarks = value;
                RaisePropertyChanged("ListBookmarks");
            }
        }

        private double fontSize;
        public double FontSize
        {
            get
            {
                return fontSize;
            }
            set
            {
                fontSize = value;
                RaisePropertyChanged("FontSize");
            }
        }

        private ObservableCollection<CustomColor> listTextColor;
        public ObservableCollection<CustomColor> ListTextColor
        {
            get
            {
                return listTextColor;
            }
            set
            {
                listTextColor = value;
                RaisePropertyChanged("ListTextColor");
            }
        }

        private ObservableCollection<CustomColor> listBackgroundColor;
        public ObservableCollection<CustomColor> ListBackgroundColor
        {
            get
            {
                return listBackgroundColor;
            }
            set
            {
                listBackgroundColor = value;
                RaisePropertyChanged("ListBackgroundColor");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(String propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public void Init()
        {
            LoadXmlData();
            LoadUserSetting();
            LoadRecentStories();
            LoadBookmarkParagraphs();
        }

        private void LoadXmlData()
        {
            XDocument doc = XDocument.Load("Data/Data.xml");
            List<Story> stories = (from story in doc.Elements("book").Elements("story")
                                   select new Story
                                   {
                                       Index = (string)story.Attribute("index"),
                                       Name = (string)story.Attribute("name"),
                                       ImgSrc = (string)story.Attribute("picture"),
                                       ListParas = (from para in story.Elements("para")
                                                    select new Para
                                                    {
                                                        Index = (string)para.Attribute("index"),
                                                        Paragraph = (string)para.Attribute("paragraph"),
                                                        Detail = (string)para.Attribute("detail")
                                                    }).ToList()
                                   }).ToList();

            listStoryItems.Clear();
            foreach (Story story in stories)
            {
                listStoryItems.Add(story);
                listStoriesIndex.Add(story.Index);
            }
        }

        private void LoadRecentStories()
        {
            if (IsolatedStorageSettings.ApplicationSettings.Contains(KEY_RECENT_STORIES_INDEX))
            {
                ObservableCollection<Story> listIndex = (ObservableCollection<Story>)IsolatedStorageSettings.ApplicationSettings[KEY_RECENT_STORIES_INDEX];
                if (listIndex != null)
                {
                    foreach (Story story in listIndex)
                    {
                        ListRecentStories.Add(story);
                    }
                }
            }
        }

        private void LoadBookmarkParagraphs()
        {
            if (IsolatedStorageSettings.ApplicationSettings.Contains(KEY_BOOKMARKED_PARAGRAPH))
            {
                ObservableCollection<Bookmark> listBookmark = (ObservableCollection<Bookmark>)IsolatedStorageSettings.ApplicationSettings[KEY_BOOKMARKED_PARAGRAPH];
                if (listBookmark != null)
                {
                    foreach (Bookmark bookmark in listBookmark)
                    {
                        ListBookmarks.Add(bookmark);
                    }
                }
            }
        }

        private void LoadUserSetting()
        {
            FontSize = DEFAULT_FONT_SIZE;
            Color lastTextColor = DEFAULT_TEXT_COLOR;
            Color lastBackgroundColor = DEFAULT_BACKGROUND_COLOR;
            if (IsolatedStorageSettings.ApplicationSettings.Contains(KEY_FONT_SIZE))
            {
                FontSize = (double)IsolatedStorageSettings.ApplicationSettings[KEY_FONT_SIZE];
            }

            if (IsolatedStorageSettings.ApplicationSettings.Contains(KEY_TEXT_COLOR))
            {
                lastTextColor = (Color)IsolatedStorageSettings.ApplicationSettings[KEY_TEXT_COLOR];
            }

            if (IsolatedStorageSettings.ApplicationSettings.Contains(KEY_BACKGROUND_COLOR))
            {
                lastBackgroundColor = (Color)IsolatedStorageSettings.ApplicationSettings[KEY_BACKGROUND_COLOR];
            }

            foreach (Color color in PresetColors)
            {
                ListTextColor.Add(new CustomColor(lastTextColor.Equals(color), color));
                ListBackgroundColor.Add(new CustomColor(lastBackgroundColor.Equals(color), color));
            }
        }

        public void AddNewRecentStory(Story story)
        {
            if (story == null) return;

            foreach (Story s in ListRecentStories)
            {
                if ((s.Index).Equals(story.Index))
                {
                    return;
                }
            }

            if (ListRecentStories.Count >= MAX_RECENT_STORIES)
            {
                ListRecentStories.RemoveAt(0);
            }

            ListRecentStories.Add(new Story
            {
                Index = story.Index,
                ImgSrc = story.ImgSrc
            });
        }

        public void AddNewBookmarkParagraph(Bookmark bookmark)
        {
            if (bookmark == null) return;

            foreach (Bookmark b in ListBookmarks)
            {
                if (bookmark.StoryIndex.Equals(b.StoryIndex) && bookmark.ParagraphIndex.Equals(b.ParagraphIndex))
                {
                    return;
                }
            }
            ListBookmarks.Add(bookmark);
        }

        public Story GetStory(string index)
        {
            if (ListStoryItems.Count == 0) return null;

            int pos = listStoriesIndex.IndexOf(index);
            if (pos == -1) return null;

            return ListStoryItems.ElementAt(pos);
        }

        public Color GetTextColor()
        {
            foreach (CustomColor c in ListTextColor)
            {
                if (c.IsSelected)
                {
                    return c.Value;
                }
            }

            return Colors.White;
        }

        public Color GetBackgroundColor()
        {
            foreach (CustomColor c in ListBackgroundColor)
            {
                if (c.IsSelected)
                {
                    return c.Value;
                }
            }
            return Colors.Black;
        }

        public double GetFontsize()
        {
            return FontSize;
        }

        public void updateListTextColors(Color selected)
        {
            ListTextColor.Clear();
            foreach (Color color in PresetColors)
            {
                ListTextColor.Add(new CustomColor(selected.Equals(color), color));
            }
        }

        public void updateListBackgroundColor(Color selected)
        {
            ListBackgroundColor.Clear();
            foreach (Color color in PresetColors)
            {
                ListBackgroundColor.Add(new CustomColor(selected.Equals(color), color));
            }
        }

        public void SaveTextColorSetting()
        {
            Color textColor = VM.DEFAULT_TEXT_COLOR;
            foreach (CustomColor c in App.ViewModel.ListTextColor)
            {
                if (c.IsSelected == true)
                {
                    textColor = c.Value;
                    break;
                }
            }
            if (IsolatedStorageSettings.ApplicationSettings.Contains(VM.KEY_TEXT_COLOR))
            {
                IsolatedStorageSettings.ApplicationSettings[VM.KEY_TEXT_COLOR] = textColor;
            }
            else
            {
                IsolatedStorageSettings.ApplicationSettings.Add(VM.KEY_TEXT_COLOR, textColor);
            }
        }

        public void SaveBackgroundColorSetting()
        {
            Color backgroundColor = VM.DEFAULT_BACKGROUND_COLOR;
            foreach (CustomColor c in App.ViewModel.ListBackgroundColor)
            {
                if (c.IsSelected == true)
                {
                    backgroundColor = c.Value;
                    break;
                }
            }
            if (IsolatedStorageSettings.ApplicationSettings.Contains(VM.KEY_BACKGROUND_COLOR))
            {
                IsolatedStorageSettings.ApplicationSettings[VM.KEY_BACKGROUND_COLOR] = backgroundColor;
            }
            else
            {
                IsolatedStorageSettings.ApplicationSettings.Add(VM.KEY_BACKGROUND_COLOR, backgroundColor);
            }
        }
    }
}
